import java.util.Arrays;

public class TestDemo {

    //数组注意点
    public static void main1(String[] args) {
        //数组定义三种方式：
        int[] a = {1,2,3,4,5};//用的最多
        int[] a1 = new int[3];
        int[] a2 = new int[]{1,2,3,4,5};

        //数组打印三种方式
        //1.普通方式
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i] + " ");
        }
        System.out.println();

        //2.增强for循环(foreach)
        //foreach只获取数组内容，不获取下标
        for (int x : a) {
            System.out.print(x + " ");
        }
        System.out.println();

        //3.借助Java的操作数组的工具类 Arrays.toString
        //将数组以字符串的形式输出
        String ret = Arrays.toString(a);
        System.out.println(ret);

        //数组拷贝四种方式
        //都是浅拷贝，即改变复制的数组值，会影响原来的
        int[] x = {1,2,3,4,6};
        int[] y= Arrays.copyOf(x, x.length);//最常用
        int[] y1 = Arrays.copyOfRange(x,1,3);//[1,3)
        int[] y2 = new int[x.length];
        System.arraycopy(x, 0, y2, 0, x.length);
        int[] y3 = a.clone();

        //---------------------------------------------------------------

        //二维数组
        int[][] array = {{1,2,3}, {4,5,6}};//必须要嵌套括号
        int[][] array2 = new int[][]{{1,2},{4,5,6}};//{1,2}打印不会补0
        int[][] array3 = new int[2][];//Java不能省略行，能省略列
        array3[0] = new int[3];//因为列可以自己手动配置
        array3[1] = new int[2];

        //打印二维数组三种方式
        //1.普通方式
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {
                System.out.print(array[i][j] + " ");
            }
            System.out.println();
        }
        //2.增强for循环
        for (int[] tmp : array) {
            for (int q : tmp) {
                System.out.print(q + " ");
            }
            System.out.println();
        }
        //3.Arrays
        System.out.println(Arrays.deepToString(array));
    }

    //作业
    //1.实现一个方法 avg, 以数组为参数, 求数组中所有元素的平均值(注意方法的返回值类型).
    public static double avg(int[] a){
        double sum = 0;
        for (int i = 0; i < a.length; i++) {
            sum += a[i];
        }
        return sum / a.length;
    }

    //2.实现一个方法 sum, 以数组为参数, 求数组所有元素之和.
    public static int sum(int[] a){
        int sum = 0;
        for (int i = 0; i < a.length; i++) {
            sum += a[i];
        }
        return sum;
    }

    /*3.实现一个方法transform,以数组为参数,将数组中的每个元素乘以2,并对应到数组元素.
    例如原数组为 {1, 2, 3}, 修改之后为 {2, 4, 6}*/
    public static int[] transform(int[] a){
        for (int i = 0; i < a.length; i++) {
            a[i] *= 2;
        }
        return a;
    }

    //4.实现一个方法 printArray, 以数组为参数, 循环访问数组中的每个元素, 打印每个元素的值.
    public static void printArray(int[] a){
        for (int x: a) {
            System.out.print(x + " ");
        }
    }

    //5.创建一个 int 类型的数组, 元素个数为 100, 并把每个元素依次设置为 1 - 100
    public static void main5(String[] args) {
        int[] a = new int[100];
        for (int i = 0; i < a.length; i++) {
            a[i] = i + 1;
        }
        printArray(a);
    }

    //6.给定一个整型数组, 实现冒泡排序(升序排序)
    public static void bubbleSort(int[] a){
        for (int i = 0; i < a.length - 1; i++) {
            boolean flag = false;
            for (int j = 0; j < a.length - i - 1; j++) {
                if (a[j] > a[j + 1]){
                    int tmp = a[j];
                    a[j] = a[j + 1];
                    a[j + 1] = tmp;
                    flag = true;
                }
            }
            if (true == flag){
                break;
            }
        }
    }

    //7.给定一个整型数组, 判定数组是否有序（递增）
    public static String isOrder(int[] a){
        int flag1 = 0;//条件1
        int flag2 = 0;//条件2
        int flag3 = 0;
        for (int i = 1; i < a.length; i++) {
            if (a[i] < a[i - 1]){
                flag1 = 1;
            }else if (a[i] > a[i - 1]){
                flag2 = 1;
            }
        }
        for (int i = 1; i < a.length - 1; i++) {
            if (a[i] < a[i - 1] && a[i] > a[i + 1]){
                flag3 = 1;
            }
        }
        if (flag1 == 1 && flag2 == 1 || flag3 == 1){//如果都满足，则不排序
            return "unsorted";
        }else {
            return "sorted";
        }
    }
    public static boolean isOrder_1(int[] a){
        for (int i = 0; i < a.length - 1; i++) {
            if (a[i] > a[i + 1]){
                return false;
            }
        }
        return true;
    }

    //8.给定一个有序整型数组, 实现二分查找
    public static int binarySearch(int[] a, int key){
        if (isOrder(a) == "unsorted"){
            return -1;
        }
        int left = 0;
        int right = a.length - 1;
        while(left <= right){
            int mid = (left + right) / 2;
            if (a[mid] < key){
                left = mid + 1;
            }else if(a[mid] > key){
                right = mid - 1;
            }else {
                return mid;
            }
        }
        return -1;
    }

    //9.实现一个方法 copyOf, 对一个整型数组进行拷贝, 得到一个新的数组.
    public static int[] copyOf(int[] a){
        int[] copy = new int[a.length];
        for (int i = 0; i < a.length; i++) {
            copy[i] = a[i];
        }
        return copy;
    }

    /*10.实现一个方法 toString, 把一个整型数组转换成字符串.
    例如数组 {1, 2, 3} , 返回的字符串为 "[1, 2, 3]", 注意 逗号 的位置和数量.*/
    public static String myToString(int[] a){
        if (a == null) return "null";
        String str = "[";
        for (int i = 0; i < a.length; i++) {
            str += a[i];
            if(i != a.length - 1){
                str += ",";
            }
        }
        str += "]";
        return str;
    }

    //11.一个整数数组，只有一个元素只出现一次，其余元素均出现两次。找出只出现了一次的元素。
    public static int findUni(int[] a){
        int ret = a[0];
        for (int i = 1; i < a.length; i++) {
            ret ^= a[i];
        }
        return ret;
    }

    //12.数组逆序
    public static void reverse(int[] a){
        int i = 0;
        int j = a.length - 1;
        while(i < j){
            int tmp = a[i];
            a[i] = a[j];
            a[j] = tmp;
            i++;
            j--;
        }
    }

    //13.把偶数放在奇数前
    public static void func(int[] a){
        int i = 0;
        int j = a.length - 1;
        while (i < j){
            if (a[i] % 2 == 0){
                i++;
            }else if (a[j] % 2 != 0){
                j--;
            }else {
                int tmp = a[i];
                a[i] = a[j];
                a[j] = tmp;
            }
        }
    }

}
